package cn.iocoder.yudao.module.book.service.community;

import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.book.controller.app.community.vo.CommunityPostCreateReqVO;
import cn.iocoder.yudao.module.book.controller.app.community.vo.CommunityPostRespVO;
import cn.iocoder.yudao.module.book.dal.dataobject.community.*;
import cn.iocoder.yudao.module.book.dal.mysql.community.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;

/**
 * 社区动态 Service 实现类
 *
 * @author system
 */
@Service
public class CommunityPostsServiceImpl implements CommunityPostsService {

    @Resource
    private CommunityPostsMapper communityPostsMapper;

    @Resource
    private PostImagesMapper postImagesMapper;

    @Resource
    private PostTopicsMapper postTopicsMapper;

    @Resource
    private PostLikesMapper postLikesMapper;

    @Resource
    private TopicsMapper topicsMapper;

    @Resource
    private TopicsService topicsService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createPost(@Valid CommunityPostCreateReqVO createReqVO, Integer userId) {
        // 1. 创建动态
        CommunityPostsDO post = CommunityPostsDO.builder()
                .userId(userId)
                .category(createReqVO.getCategory())
                .title(createReqVO.getTitle())
                .content(createReqVO.getContent())
                .studyDuration(createReqVO.getStudyData() != null ? createReqVO.getStudyData().getDuration() : null)
                .studyPages(createReqVO.getStudyData() != null ? createReqVO.getStudyData().getPages() : null)
                .studyContent(createReqVO.getStudyData() != null ? createReqVO.getStudyData().getContent() : null)
                .relatedBookId(createReqVO.getRelatedBookId())
                .relatedCollectionId(createReqVO.getRelatedCollectionId())
                .relatedClockId(createReqVO.getRelatedClockId())
                .likesCount(0)
                .commentsCount(0)
                .sharesCount(0)
                .status(1)
                .isTop(0)
                .build();
        communityPostsMapper.insert(post);

        // 2. 保存图片
        if (createReqVO.getImages() != null && !createReqVO.getImages().isEmpty()) {
            List<PostImagesDO> images = new ArrayList<>();
            for (int i = 0; i < createReqVO.getImages().size(); i++) {
                PostImagesDO image = PostImagesDO.builder()
                        .postId(post.getPostId())
                        .imageUrl(createReqVO.getImages().get(i))
                        .imageOrder(i)
                        .build();
                images.add(image);
            }
            postImagesMapper.insertBatch(images);
        }

        // 3. 保存话题关联
        if (createReqVO.getTags() != null && !createReqVO.getTags().isEmpty()) {
            List<PostTopicsDO> postTopics = new ArrayList<>();
            for (String tagName : createReqVO.getTags()) {
                Long topicId = topicsService.createOrGetTopic(tagName);
                PostTopicsDO postTopic = PostTopicsDO.builder()
                        .postId(post.getPostId())
                        .topicId(topicId)
                        .build();
                postTopics.add(postTopic);

                // 更新话题动态数量
                topicsMapper.updatePostsCount(topicId, 1);
            }
            postTopicsMapper.insertBatch(postTopics);
        }

        return post.getPostId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deletePost(Long postId, Integer userId) {
        // 1. 验证动态是否存在且属于当前用户
        CommunityPostsDO post = communityPostsMapper.selectById(postId);
        if (post == null) {
            throw ServiceExceptionUtil.exception(BAD_REQUEST, "动态不存在");
        }
        if (!post.getUserId().equals(userId)) {
            throw ServiceExceptionUtil.exception(BAD_REQUEST, "无权限删除此动态");
        }

        // 2. 删除动态（软删除）
        post.setStatus(-1);
        communityPostsMapper.updateById(post);

        // 3. 删除相关数据
        postImagesMapper.deleteByPostId(postId);

        // 4. 更新话题动态数量
        List<PostTopicsDO> postTopics = postTopicsMapper.selectByPostId(postId);
        for (PostTopicsDO postTopic : postTopics) {
            topicsMapper.updatePostsCount(postTopic.getTopicId(), -1);
        }
        postTopicsMapper.deleteByPostId(postId);
    }

    @Override
    public CommunityPostRespVO getPostDetail(Long postId, Integer userId) {
        // 1. 查询动态
        CommunityPostsDO post = communityPostsMapper.selectById(postId);
        if (post == null || post.getStatus() != 1) {
            throw ServiceExceptionUtil.exception(BAD_REQUEST, "动态不存在");
        }

        // 2. 转换为VO
        return convertToRespVO(post, userId);
    }

    @Override
    public PageResult<CommunityPostRespVO> getPostsPage(String category, Integer page, Integer pageSize,
            Integer userId, Integer targetUserId, Long topicId) {
        // 1. 查询动态列表
        PageResult<CommunityPostsDO> pageResult;
        if (topicId != null) {
            // 根据话题查询
            List<CommunityPostsDO> posts = communityPostsMapper.selectPostsByTopicId(topicId,
                    (page - 1) * pageSize, pageSize);
            pageResult = new PageResult<>(posts, (long) posts.size());
        } else {
            // 普通查询
            pageResult = communityPostsMapper.selectPostsPage(category, targetUserId, topicId, page, pageSize);
        }

        // 2. 转换为VO
        List<CommunityPostRespVO> respVOs = pageResult.getList().stream()
                .map(post -> convertToRespVO(post, userId))
                .collect(Collectors.toList());

        return new PageResult<>(respVOs, pageResult.getTotal());
    }

    @Override
    public PageResult<CommunityPostRespVO> searchPosts(String keyword, String category, Integer page,
            Integer pageSize, Integer userId) {
        // 1. 搜索动态
        List<CommunityPostsDO> posts = communityPostsMapper.searchPosts(keyword, category,
                (page - 1) * pageSize, pageSize);

        // 2. 转换为VO
        List<CommunityPostRespVO> respVOs = posts.stream()
                .map(post -> convertToRespVO(post, userId))
                .collect(Collectors.toList());

        return new PageResult<>(respVOs, (long) respVOs.size());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer likePost(Long postId, Integer userId) {
        // 1. 检查是否已点赞
        PostLikesDO existingLike = postLikesMapper.selectPostLike(postId, userId);
        if (existingLike != null && existingLike.getStatus() == 1) {
            throw ServiceExceptionUtil.exception(BAD_REQUEST, "已经点赞过了");
        }

        // 2. 创建或更新点赞记录
        if (existingLike == null) {
            PostLikesDO like = PostLikesDO.builder()
                    .postId(postId)
                    .userId(userId)
                    .likeType(1)
                    .status(1)
                    .build();
            postLikesMapper.insert(like);
        } else {
            existingLike.setStatus(1);
            postLikesMapper.updateById(existingLike);
        }

        // 3. 更新动态点赞数
        communityPostsMapper.updateLikesCount(postId, 1);

        // 4. 返回最新点赞数
        CommunityPostsDO post = communityPostsMapper.selectById(postId);
        return post.getLikesCount();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer unlikePost(Long postId, Integer userId) {
        // 1. 检查点赞记录
        PostLikesDO existingLike = postLikesMapper.selectPostLike(postId, userId);
        if (existingLike == null || existingLike.getStatus() == 0) {
            throw ServiceExceptionUtil.exception(BAD_REQUEST, "还未点赞");
        }

        // 2. 取消点赞
        existingLike.setStatus(0);
        postLikesMapper.updateById(existingLike);

        // 3. 更新动态点赞数
        communityPostsMapper.updateLikesCount(postId, -1);

        // 4. 返回最新点赞数
        CommunityPostsDO post = communityPostsMapper.selectById(postId);
        return post.getLikesCount();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer sharePost(Long postId, Integer userId) {
        // 更新分享数
        communityPostsMapper.updateSharesCount(postId, 1);

        // 返回最新分享数
        CommunityPostsDO post = communityPostsMapper.selectById(postId);
        return post.getSharesCount();
    }

    /**
     * 转换为响应VO
     */
    private CommunityPostRespVO convertToRespVO(CommunityPostsDO post, Integer userId) {
        CommunityPostRespVO respVO = new CommunityPostRespVO();
        respVO.setPostId(post.getPostId());
        respVO.setUserId(post.getUserId());

        // 设置用户信息（这里简化处理，实际项目中应该查询用户表）
        respVO.setUsername("用户" + post.getUserId());
        respVO.setAvatar("https://example.com/avatar/default.jpg");

        respVO.setCategory(post.getCategory());
        respVO.setCategoryName(getCategoryName(post.getCategory()));
        respVO.setTitle(post.getTitle());
        respVO.setContent(post.getContent());
        respVO.setStudyDuration(post.getStudyDuration());
        respVO.setStudyPages(post.getStudyPages());
        respVO.setStudyContent(post.getStudyContent());
        respVO.setLikesCount(post.getLikesCount());
        respVO.setCommentsCount(post.getCommentsCount());
        respVO.setSharesCount(post.getSharesCount());
        respVO.setCreateTime(post.getCreateTime());
        respVO.setTime(formatRelativeTime(post.getCreateTime()));

        // 查询图片
        List<PostImagesDO> images = postImagesMapper.selectByPostId(post.getPostId());
        respVO.setImages(images.stream().map(PostImagesDO::getImageUrl).collect(Collectors.toList()));

        // 查询话题
        List<PostTopicsDO> postTopics = postTopicsMapper.selectByPostId(post.getPostId());
        List<String> topicNames = new ArrayList<>();
        for (PostTopicsDO postTopic : postTopics) {
            TopicsDO topic = topicsMapper.selectById(postTopic.getTopicId());
            if (topic != null) {
                topicNames.add(topic.getTopicName());
            }
        }
        respVO.setTopics(topicNames);

        // 查询是否已点赞
        if (userId != null) {
            PostLikesDO like = postLikesMapper.selectPostLike(post.getPostId(), userId);
            respVO.setIsLiked(like != null && like.getStatus() == 1);
        } else {
            respVO.setIsLiked(false);
        }

        return respVO;
    }

    /**
     * 获取分类名称
     */
    private String getCategoryName(String category) {
        switch (category) {
            case "experience":
                return "经验分享";
            case "study":
                return "学习记录";
            case "qa":
                return "问答求助";
            case "resource":
                return "资源推荐";
            default:
                return "其他";
        }
    }

    /**
     * 格式化相对时间
     */
    private String formatRelativeTime(LocalDateTime createTime) {
        LocalDateTime now = LocalDateTime.now();
        long minutes = ChronoUnit.MINUTES.between(createTime, now);

        if (minutes < 1) {
            return "刚刚";
        } else if (minutes < 60) {
            return minutes + "分钟前";
        } else if (minutes < 1440) { // 24小时
            return (minutes / 60) + "小时前";
        } else if (minutes < 10080) { // 7天
            return (minutes / 1440) + "天前";
        } else {
            return createTime.format(DateTimeFormatter.ofPattern("MM-dd"));
        }
    }

}
